// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;

namespace SnapObjects.Data
{
    internal abstract class InsertBuilderParser : SqlBuilderParser
    {
        public InsertBuilderParser(
            ISqlStatementFactory factory,
            ISqlGenerationHelper helper,
            ITypeMapper typeMapper) : base(factory, helper, typeMapper)
        {
        }

        public override SqlStatement Parse(SqlBuildStatement statement)
        {
            var stmt = new SqlInsertStatement();

            var insert = (InsertBuildStatement)statement;

            this.ParseBuildParameters(insert);

            if (!this.ParseClause(insert, stmt.Table, insert.Table, SqlWhitespaceToken.Whitespace))
            {
                throw new InvalidCastException("Missing insert table.");
            }

            for (var i = 0; i < insert.Columns.Count; i++)
            {
                if (insert.Columns[i] is ColumnElement column)
                {
                    stmt.Into.Add(new SqlIdentifierToken(column.ColumnName));

                    switch (column.ValueType)
                    {
                        case SqlRightType.Clause:
                        {
                            stmt.Values.Add(new SqlCharacterToken(SqlCharacters.OpenParentheses));
                            stmt.Values.AddRange(this.ParseRawString(insert, (string)column.Value));
                            stmt.Values.Add(new SqlCharacterToken(SqlCharacters.CloseParentheses));
                        }
                        break;
                        case SqlRightType.Parameter:
                        {
                            var parameter = (ISqlBuilderParameter)column.Value;

                            stmt.Values.Add(new SqlParameterToken(parameter.Name));
                        }
                        break;
                        case SqlRightType.Value:
                        {
                            stmt.Values.Add(new SqlValueToken(column.Value));
                        }
                        break;
                        case SqlRightType.Statement:
                        {

                        }
                        break;
                    }

                    if (i < insert.Columns.Count - 1)
                    {
                        stmt.Into.Add(new SqlCharacterToken(SqlCharacters.Comma));
                        stmt.Values.Add(new SqlCharacterToken(SqlCharacters.Comma));
                    }
                }
            }

            return stmt;
        }
    }
}
